/*
 *  GEVector3d.h
 *  TestGE
 *
 *  Created by Quoc Dung Chu on 15/07/11.
 *  Copyright 2011 Paris 6. All rights reserved.
 *
 */

#ifndef GE_VECTOR_3D_H
#define GE_VECTOR_3D_H

#include <math.h>
#include "GETuple3d.h"
namespace game_engine
{
	namespace vect_math
	{
		
		template <class T>
		class GEVector3d : public GETuple3d<T> {
		public:
			
			GEVector3d(T x, T y, T z):GETuple3d<T>(x,y,z) {}
			//------------------------------------------------------------------
			T length() const 
			{ 
				return vect_math::squareroot(   this->X * this->X 
											  + this->Y * this->Y 
											  + this->Z * this->Z ); 
			}
			//------------------------------------------------------------------

			T lengthSquared() const
			{
				return this->X * this->X + this->Y * this->Y + this->Z * this->Z;
			}
			//------------------------------------------------------------------

			T dot( const GEVector3d<T>& other ) const
			{
				return this->X * other.X + this->Y * other.Y + this->Z * other.Z; 
			}
			
			//------------------------------------------------------------------
			//T cross( const GEVector3d<T>& other) const
//			{
//				return 
//			}
			
			//------------------------------------------------------------------

			float angleD( const GEVector3d<T>& other ) const
			{
				return radianToDegree(this->angleR(other));
			}
			//------------------------------------------------------------------
			float angleR( const GEVector3d<T>& other ) const
			{
				return acos(static_cast<float>(this->dot(other))
							 /static_cast<float>(this->length() * other.length()));
			}
			//------------------------------------------------------------------
#pragma mark -			
#pragma mark OPERATOR
			
			GEVector3d<T> operator-() 
			{ 
				return GEVector3d<T>(-this->X,-this->Y,-this->Z);
			}
			
			GEVector3d<T> operator+ (const GEVector3d<T>& other) 
			{ 
				return GEVector3d<T>(this->X + other.X, this->Y + other.Y, this->Z + other.Z);
			}
			
			GEVector3d<T> operator+ (const T val) 
			{ 
				return GEVector3d<T>(this->X + val, this->Y + val, this->Z + val);
			}
			
			GEVector3d<T> operator- (const GEVector3d<T>& other) 
			{ 
				return GEVector3d<T>(this->X - other.X, this->Y - other.Y, this->Z - other.Z);
			}
			
			GEVector3d<T> operator- (const T val) 
			{ 
				return GEVector3d<T>(this->X - val, this->Y - val, this->Z - val);
			}
			
			
			GEVector3d<T> operator* (const GEVector3d<T>& other) 
			{ 
				return GEVector3d<T>(this->X * other.X, this->Y * other.Y, this->Z * other.Z);
			}
			
			GEVector3d<T> operator* (const T val) 
			{ 
				return GEVector3d<T>(this->X * val, this->Y * val, this->Z * val);
			}
			
			GEVector3d<T> operator/ (const GEVector3d<T>& other) 
			{ 
				return GEVector3d<T>(this->X / other.X, this->Y / other.Y, this->Z / other.Z);
			}
			
			GEVector3d<T> operator/ (const T val) 
			{ 
				return GEVector3d<T>(this->X / val, this->Y / val, this->Z / val);
			}
			
		};
	}
}

#endif